using System;
using System.Collections.Generic;
using UnityEngine;

namespace Yoozoo.Gameplay.City
{
    [Serializable]
    public class CityFloorNodeData
    {
        // ID
        public uint id;
        // 名称
        public string name;
        // 位置
        public Vector3 localPosition;
        // 旋转
        public Vector3 localEulerAngles;
        // 缩放
        public Vector3 localScale;
        // active
        public bool active;
        
        // prefab
        public string prefabPath;

        // children
        public List<uint> childrenIds;
        // ScriptableObject不支持递归嵌套多层！！！
        [NonSerialized]
        public List<CityFloorNodeData> children;
    }

    [Serializable]
    public class CityFloorAreaData
    {
        // 区域ID
        public int areaId;
        // 节点名称
        public string name;
        
        // Wall节点
        public CityFloorNodeData wallNode;
        
        // Ground节点
        public CityFloorNodeData groundNode;
        // 解锁Floor节点
        public CityFloorNodeData unlockFloorNode;
        // 解锁Floor特效节点
        public CityFloorNodeData unlockEffectNode;
        // 未解锁Floor节点
        public CityFloorNodeData lockFloorNode;
        // 集装箱特效节点
        public CityFloorNodeData containerEffectNode;

        // 需要显示的围墙 (相对于Root节点的Hierarchy路径)
        public List<string> showWallHierarchyPaths;
    }

    [Serializable]
    public class CityFloorDataConfig : ScriptableObject
    {
        public List<CityFloorAreaData> areas;

        // 平铺所有节点信息（ScriptableObject不支持递归嵌套多层）
        public List<CityFloorNodeData> nodes;

        /// <summary>
        /// 序列化 (将嵌套树状节点数据平铺)
        /// </summary>
        public void Serialize()
        {
            uint id = 0;

            nodes = new List<CityFloorNodeData>();
            // 为所有Node生成id，并保存
            foreach (var cityFloorAreaData in areas)
            {
                // Wall节点
                if (cityFloorAreaData.wallNode != null)
                {
                    traverseToStore(cityFloorAreaData.wallNode, ref id);
                }
                // Ground节点
                if (cityFloorAreaData.groundNode != null)
                {
                    traverseToStore(cityFloorAreaData.groundNode, ref id);
                }
                // 解锁Floor节点
                if (cityFloorAreaData.unlockFloorNode != null)
                {
                    traverseToStore(cityFloorAreaData.unlockFloorNode, ref id);
                }
                // 解锁Floor特效节点
                if (cityFloorAreaData.unlockEffectNode != null)
                {
                    traverseToStore(cityFloorAreaData.unlockEffectNode, ref id);
                }
                // 未解锁Floor节点
                if (cityFloorAreaData.lockFloorNode != null)
                {
                    traverseToStore(cityFloorAreaData.lockFloorNode, ref id);
                }
                // 集装箱特效节点
                if (cityFloorAreaData.containerEffectNode != null)
                {
                    traverseToStore(cityFloorAreaData.containerEffectNode, ref id);
                }
            }
        }

        /// <summary>
        /// 反序列化 (将平铺的节点信息转换成嵌套树形节点数据结构)
        /// </summary>
        public void Deserialize()
        {
            Dictionary<uint, CityFloorNodeData> nodesDict = new Dictionary<uint, CityFloorNodeData>(nodes.Count);
            
            // 1.初始化节点字典
            foreach (var node in nodes)
            {
                nodesDict.Add(node.id, node);
            }
            // 2.初始化节点Children
            foreach (var node in nodes)
            {
                deserializeNodeChildren(node, nodesDict);
            }
            foreach (var cityFloorAreaData in areas)
            {
                // Wall节点
                deserializeNodeChildren(cityFloorAreaData.wallNode, nodesDict);
                // Ground节点
                deserializeNodeChildren(cityFloorAreaData.groundNode, nodesDict);
                // 解锁Floor节点
                deserializeNodeChildren(cityFloorAreaData.unlockFloorNode, nodesDict);
                // 解锁Floor特效节点
                deserializeNodeChildren(cityFloorAreaData.unlockEffectNode, nodesDict);
                // 未解锁Floor节点
                deserializeNodeChildren(cityFloorAreaData.lockFloorNode, nodesDict);
                // 集装箱特效节点
                deserializeNodeChildren(cityFloorAreaData.containerEffectNode, nodesDict);
            }
        }

        // 序列化保存节点
        private void traverseToStore(CityFloorNodeData node, ref uint id)
        {
            node.id = ++id;
            nodes.Add(node);
            if (node.children != null)
            {
                node.childrenIds = new List<uint>();
                foreach (var childNode in node.children)
                {
                    traverseToStore(childNode, ref id);
                    node.childrenIds.Add(childNode.id);
                }
            }
        }
        
        // 反序列化解析节点
        void deserializeNodeChildren(CityFloorNodeData node, Dictionary<uint, CityFloorNodeData> nodesDict)
        {
            if (node.childrenIds!=null && node.childrenIds.Count > 0)
            {
                node.children = new List<CityFloorNodeData>();
                for (int i = 0; i < node.childrenIds.Count; ++i)
                {
                    node.children.Add(nodesDict[node.childrenIds[i]]);
                }
            }
        }
        
    }
}